#include <rasqal.h>
#include <redland.h>
#include <raptor2.h>
#include <rasqal.h>
#define RASQAL_INTERNAL
#include <rasqal_internal.h>
#include <raptor_internal.h>
#include <string>
#include <iostream>
#include <string>
#include <QtCore>

#ifndef _QUERYPARSER_H_
#define _QUERYPARSER_H_

/*
 * A table of variables with optional binding values
 *
 * variables are named or anonymous (cannot be selected).
 */
struct rasqal_variables_table_s {
  rasqal_world* world;

  /* usage/reference count */
  int usage;

  /* The variables of size @variables_count + @anon_variables_count
   * shared pointers into @variables_sequence and @anon_variables_sequence
   */
  rasqal_variable** variables;

  /* Named variables (owner) */
  raptor_sequence* variables_sequence;
  int variables_count;

  /* Anonymous variables (owner) */
  raptor_sequence* anon_variables_sequence;
  int anon_variables_count;

  /* array of variable names.  The array is allocated here but the
   * pointers are into the #variables_sequence above.  It is only
   * allocated if rasqal_variables_table_get_names() is called
   * on demand, otherwise is NULL.
   */
  const unsigned char** variable_names;
};



/*
 * Sequence of maximum capacity C containing N data items
 *
 * array:
 *    0            <-- N consecutive items -->         C - 1
 * -----------------------------------------------------------
 * |      |      | data1 |  .....     data N |  ...  |       |
 * -----------------------------------------------------------
 * ------ O -----> offset of first data item
 *
 * start    = O
 * size     = N
 * capacity = C
 *
 */
struct raptor_sequence_s {
  /* how many items are in the sequence 0..capacity */
  int size;

  /* length of the 'sequence' array below */
  int capacity;

  /* offset of the first data item in the sequence: 0..capacity-1 */
  int start;

  /* array of size 'capacity' pointing to the data */
  void **sequence;


  /* handler to call to free a data item (or NULL) */
  raptor_data_free_handler free_handler;

  /* handler to call to print a data item (or NULL) */
  raptor_data_print_handler print_handler;


  /* context pointer for @context_free_handler and @context_print_handler */
  void *handler_context;

  /* handler to call to free a data item (or NULL) also passing in
   * as first arg the @handler_context
   */
  raptor_data_context_free_handler context_free_handler;

  /* handler to call to print a data item (or NULL) also passing in
   * as first arg the @handler_context
   */
  raptor_data_context_print_handler context_print_handler;
};


class QueryParser{
public:
	QueryParser();
	~QueryParser();
	void analyze(std::string whole_query_cmd);

private:
	int rasqal_query_prepare2(rasqal_query* query,const unsigned char *query_string,raptor_uri *base_uri);
	int get_subquery_number(rasqal_query* rq);
	int subquery_return(rasqal_query* rq, std::string *subquery, std::string (*subquery_element)[3],  int (*subquery_pattern)[4]);
	void subquery_get_variables(rasqal_query* rq,int& variable_size,std::string* variables);
	int subquery_to_Co(std::string element[3],int (*subquery_pattern)[4]);


public:
    char* query_cmd;
    char* subquery_cmd;
    std::string subquery_array[100];
    std::string subquery_variable_array[100][3]; //子查询的子元素列表
    std::string subquery_variable[3];//单条子查询的变量列表
    const char *ql_name;
    rasqal_query *rq;
    rasqal_world* rasq_world;
    int subquery_size;
    int (*subquery_pattern)[4];
    int dest_db; //指示查询的数据库位置（一共有28个数据库地址）
    int variable_size; //目标变量的数目
    std::string variables[10]; //目标变量的数组
};


#endif //_QUERYPARSER_H_
